
import { _decorator, Component, Node, Vec3, CCLoader, v3, BoxCollider2D, ERigidBody2DType, RigidBody2D, size, v2, CircleCollider2D } from 'cc';
import LevelColler from '../../MainScene/Script/LevelColler';
import GameConfig from '../../Script/GameSpecial/GameConfig';
import { EventType } from '../../Script/GameSpecial/GameEventType';
import { GlobalEnum } from '../../Script/GameSpecial/GlobalEnum';
const { ccclass, property } = _decorator;

@ccclass('GoldItem')
export class GoldItem extends LevelColler {
    public static radian: number = 0;
    public static sinY: number = 0;
    public static cosY: number = 0;

    protected initSub() {
        this.initAABB();
        this.initJumpState();
        this.initRigidNode();
    }

    protected registAllCustomUpdate() {
        this.registCustomUpdate(AnimStep.droped, this.stepDroped);
        this.registCustomUpdate(AnimStep.jump, this.stepJump);
    }

    protected setData(data: { p: Vec3 }) {
        this.setPosition(data.p);
        this.cachePos.set(data.p);
        this.meshNode.setRotation(0, 0, 0, 1);
    }

    public enterLevel(speed: Vec3) {
        this.speedY = speed.y;
        this.enableRigidNode();
        let r = GameConfig.GameRule.rate3to2;
        this.cacheLinearVelocity.x = speed.x * r;
        this.cacheLinearVelocity.y = -speed.z * r;
        this.rigid.linearVelocity = this.cacheLinearVelocity;
        this.enterCustomUpdateState(AnimStep.jump);
    }

    public onColled(other) {
        other.getGold();
        this.emit(EventType.LevelEvent.removeGold, this);
    }

    protected speedY: number;
    protected gravity: number;
    protected cachePos: Vec3;
    protected meshNode: Node = null;
    protected initJumpState() {
        this.speedY = 0;
        this.gravity = -50;
        this.cachePos = new Vec3();
        this.meshNode = this.node.children[0];
    }
    protected stepJump(dt: number) {
        // this.meshNode.setRotation(0, GoldItem.sinY, 0, GoldItem.cosY);
        this.speedY += this.gravity * dt;
        this.cachePos.y += this.speedY * dt;
        if (this.cachePos.y <= 0) {
            this.cachePos.y = 0;
            this.syncRigidToModel();
            this.disableRigidNode();
            this.enterCustomUpdateState(AnimStep.droped);
            this.emit(EventType.LevelEvent.addGoldColler, this);
        }
    }
    protected stepDroped(dt: number) {
        this.meshNode.setRotation(0, GoldItem.sinY, 0, GoldItem.cosY);
    }

    /**在2D物理世界生成一个碰撞体替身 */
    protected createRigidNode() {
        if (!!this.rigidNode) return;
        //碰撞体节点
        let node = new Node(GlobalEnum.RigidNode.role);
        this.rigidNode = node;
        //刚体组件
        let rigid = node.addComponent(RigidBody2D);
        rigid.group = GlobalEnum.RigidGroup.gold;
        rigid.enabledContactListener = false;
        rigid.bullet = false;
        rigid.type = ERigidBody2DType.Dynamic;
        rigid.allowSleep = false;
        rigid.gravityScale = 0;
        rigid.linearDamping = 0.5;
        rigid.angularDamping = 0.5;
        rigid.linearVelocity = v2(0, 0);
        rigid.angularVelocity = 0;
        rigid.fixedRotation = true;
        rigid.awakeOnLoad = true;
        this.rigid = rigid;
        //碰撞体形状
        let collider = node.addComponent(CircleCollider2D);
        collider.tag = 0;
        collider.group = GlobalEnum.RigidGroup.gold;
        collider.density = 1;
        collider.sensor = false;
        collider.friction = 0;
        collider.restitution = 0;
        collider.offset = v2(0, 0);
        let r = GameConfig.GameRule.rate3to2;
        collider.radius = 0.4 * r;
        this.collider2d = collider;
    }

    /**将碰撞体信息同步到3D节点 */
    public syncRigidToModel() {
        //坐标
        if (this.rigid.linearVelocity.x != 0 || this.rigid.linearVelocity.y != 0) {
            let p = this.rigidNode.position;
            let r = GameConfig.GameRule.rate2to3;
            let x = p.x * r;
            let y = this.cachePos.y;
            let z = -p.y * r;
            this.node.setPosition(x, y, z);
            this.aabbDirty = true;
        }
    }

}

enum AnimStep {
    jump,
    droped,
}
